#include <stdio.h>
#include <stdlib.h>
#include "mpx_supt.h"
#include <string.h>
#include "mrj_supt.h"
pcb *searchPriority(int);

pcb *pHeadR;
pcb *pTailR;
pcb *pHeadB;
pcb *pTailB;
int countb;  //blocked queue count
int countr;  //ready queue count

void enqueueBlocked(pcb element)
{
	if(countb == 0)   //First element
	{
		pHeadB = &element;   //first element is at the head of queue
		pTailB = &element;   //first element is at the tail of queue
		countb++;   
	}
	
	else
	{
		element.next = pTailB;   //set next to the tail element
		element.prev = NULL;    //set previous to NULL
		pTailB = &element;            //set tail pointer to the element
		countb++;
	}
}

pcb dequeueBlocked()
{
	pcb *pTemp = NULL;
	if(countb == 0)
	{
		printf("The queue is empty.");
	}
	
	else
	{
		pTemp = pHeadB;               //Hold the value to be dequed in temp pointer
		pHeadB = pTemp->prev;     //Assign new head to previous pcb
		countb--;
	}
	
	return *pTemp;             //Return head pcb
}
		
void enqueueReady(pcb* element)
{
	if(countr == 0)   //First element
	{
		pHeadR = element;   //first element is at the head of queue
		pTailR = element;   //first element is at the tail of queue
		countr++;
	}

	else
	{
		pcb *pBehind = (searchPriority(element->priority)); //search to find element priority
		
		printf("SEARCH PRIORITY RESULTS: %s\n", pBehind->name);

		if((pBehind == pTailR)&&(pBehind != pHeadR))       //If element has lowest priority
		{
			element->next = pTailR->next;  //set element's next to tail's next
			element->prev = NULL;               //no previous node
			pTailR = element;  			//set tail pointer to the element
			countr++;
		}
		
		else if((pBehind == pHeadR))       //If element has highest priority
		{
			element->prev = pBehind;    //set previous to the element behind the new element
			element->next = NULL;  //set next to NULL
			pBehind->next = element;    //set behind element's next to the new element
			pHeadR = element;
			countr++;
		}

		else
		{
			element->prev = pBehind;    //set previous to the element behind the new element
			element->next = pBehind->next;  //set next to behind's next
			pBehind->next = element;    //set behind element's next to the new element
			countr++;
		}
	}
	printf("IN ENQUEUE pHEADR: %s, %d, %d\n", pHeadR->name, pHeadR->priority, pHeadR->Pclass);
	printf("COUNT = %d\n", countr);
	printf("IN ENQUEUE pHEADR's prev: %s, %d, %d\n", pHeadR->prev->name, pHeadR->prev->priority, pHeadR->prev->Pclass);
	printf("IN ENQUEUE pTAILR: %s, %d, %d\n", pTailR->name, pTailR->priority, pTailR->Pclass);
}

pcb dequeueReady()
{
	pcb *pTemp = NULL;
	if(countr == 0)
	{
		printf("The queue is empty.");
	}

	else
	{
		pTemp = pHeadR;               //Hold the value to be dequed in temp pointer
		pHeadR = pTemp->prev;     //Assign new head to previous pcb
		countr--;
	}

	return *pTemp;             //Return head pcb
}

pcb* searchPriority(int newPriority)
{
	pcb *pElementBehindNewElement;
	pcb *pTemp;
	pTemp = &pHeadR;
	
	printf("IN SEARCH PRIORITY: %s\n", pHeadR->name);

	if(newPriority > (pHeadR->priority))   //Highest Priority
	{
		pElementBehindNewElement = pHeadR;
	}

	else if(newPriority < (pTailR->priority))  //Lowest priority
	{
		pElementBehindNewElement = pTailR;
	}

	else
	{
		while(newPriority < (pTemp->priority))   //check if new element's priority is less than temp's
		{
			pTemp = pTemp->prev;  //Search backwards from head
		}

		pElementBehindNewElement = pTemp;
	}

	return pElementBehindNewElement;
}

pcb* searchPCBbyName(char* name)
{
	pcb* pTemp = pHeadR;   //Starts with seaching at the head of the ready queue
	int notHere = 0;     //Indicator as to whether or not the pcb is found
	
	printf("SEARCHBYNAME PHEAD'S NAME: %s\n", pHeadR->name);

	while((strcmp(pTemp->name, name) != 0) && (notHere == 0)) //Search through ready queue
	{
		if(pTemp == pTailR) { notHere = 1;}  //At end of queue
		
		else if(countr == 0) { notHere = 1;} //Empty queue

		else
		{pTemp = pTemp->prev;}  //Not at end, keep looking
	}

	if(notHere == 1)   //Wasn't found in ready queue
	{
		notHere = 0;   //Reset notHere indicator
		pTemp = pHeadB;   //Set temp pointer to the blocked queue head

		while((strcmp(pTemp->name, name) != 0) && (notHere == 0)) //Search through blocked queue
		{
			if(pTemp == pTailB) { notHere = 1;}  //At end of queue
			
			else if(countb == 0) { notHere = 1;}  //Empty queue

			else
			{pTemp = pTemp->prev;}  //Not at end, keep looking
		}
	}

	if(notHere == 1)         //Wasn't found in either queue
	{
		printf("%s was not found.\n", name);
		return 0;
	}
	printf("SEARCHBYNAME: %s , %s\n", pTemp->name, name);
	printf("%s\n", pHeadR->name);
	printf("%d\n", countr);

	return pTemp;
}
